Skip to content

fix(stainless): rename simulate.return → simulate.refund to avoid Kotlin keyword#520

Closed
pengying wants to merge 1 commit into
mainfrom
05-27-fix_stainless_rename_simulate.return_simulate.refund_to_avoid_kotlin_keyword
Closed

fix(stainless): rename simulate.return → simulate.refund to avoid Kotlin keyword#520
pengying wants to merge 1 commit into
mainfrom
05-27-fix_stainless_rename_simulate.return_simulate.refund_to_avoid_kotlin_keyword

Conversation

@pengying
Copy link
Copy Markdown
Contributor

@pengying pengying commented May 28, 2026

Summary

Renames the Stainless method sandbox.cards.simulate.returnsandbox.cards.simulate.refund to avoid the Kotlin reserved keyword return.

Why

After #518, Stainless codegen emits a warning:

Encountered name return that conflicts with a Kotlin keyword. Renamed to return_.

That gives consumers awkward call sites like grid.sandbox.cards.simulate.return_(...) in Kotlin. The endpoint creates a CardRefund (per the POST /sandbox/cards/{id}/simulate/return description: "Simulate a merchant-initiated RETURN against an existing settled card transaction... Creates a CardRefund..."), so refund is both semantically accurate and reads cleanly across all SDK targets.

Changes

  • .stainless/stainless.yml: rename the method key in sandbox.subresources.cards.subresources.simulate.methods from returnrefund. The underlying OpenAPI path is unchanged (/sandbox/cards/{id}/simulate/return); only the SDK identifier changes.

SDK call site impact

Language Before After
Kotlin simulate.return_(...) simulate.refund(...)
TypeScript simulate.return(...) simulate.refund(...)
Python simulate.return_(...) (reserved) simulate.refund(...)

Method has not shipped in any GA SDK yet, so no compatibility shim is needed.

Test plan

  • Stainless regen succeeds without the keyword-conflict warning
  • Kotlin SDK compiles

@vercel
Copy link
Copy Markdown

vercel Bot commented May 28, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
grid-flow-builder Ready Ready Preview, Comment May 28, 2026 11:09pm

Request Review

Copy link
Copy Markdown
Contributor Author

pengying commented May 28, 2026

@greptile-apps
Copy link
Copy Markdown
Contributor

greptile-apps Bot commented May 28, 2026

Greptile Summary

This PR renames the Stainless SDK method alias simulate.return to simulate.refund to avoid a conflict with the return reserved keyword in Kotlin. The underlying HTTP endpoint path (/sandbox/cards/{id}/simulate/return) is unchanged — only the generated SDK method name is affected.

  • The rename is consistent with the existing card_refund_summary model name already present in the same config block, making the naming cohesive across the resource.
  • No other files are affected; the change is isolated to a single line in .stainless/stainless.yml.

Confidence Score: 5/5

Safe to merge — one-line rename in the Stainless config with no changes to the HTTP endpoint or any application logic.

The change is a single alias rename in stainless.yml. The HTTP path is preserved, the new name aligns with the existing card_refund_summary model, and there is no risk of breaking existing API consumers — only generated SDK method names change.

No files require special attention.

Important Files Changed

Filename Overview
.stainless/stainless.yml Renames the simulate.return method alias to simulate.refund in the Stainless SDK config while keeping the underlying HTTP path unchanged; consistent with the existing card_refund_summary model name.

Sequence Diagram

sequenceDiagram
    participant KotlinSDK as Kotlin SDK Client
    participant StainlessGen as Stainless SDK Generator
    participant API as Grid API

    Note over StainlessGen: stainless.yml: refund → /simulate/return
    KotlinSDK->>StainlessGen: sandbox.cards.simulate.refund(id)
    StainlessGen->>API: "POST /sandbox/cards/{id}/simulate/return"
    API-->>StainlessGen: 200 OK (CardRefundSummary)
    StainlessGen-->>KotlinSDK: CardRefundSummary
Loading

Reviews (1): Last reviewed commit: "fix(stainless): rename simulate.return →..." | Re-trigger Greptile

@pengying pengying force-pushed the 05-27-fix_stainless_rename_simulate.return_simulate.refund_to_avoid_kotlin_keyword branch from ca8e445 to f8ea7ca Compare May 28, 2026 23:09
@pengying
Copy link
Copy Markdown
Contributor Author

this is also captured in 525 so closing for now

@pengying pengying closed this May 29, 2026
pengying added a commit that referenced this pull request May 29, 2026
…#521)

## Summary

Two changes that together close a hole in our spec hygiene: a Spectral rule that catches every `oneOf` missing a discriminator (not just top-level schemas), and the one existing violation (`Card.stateReason`).

## Why

Stainless's Java codegen emitted the diagnostic:

> `Java/SchemaUnionDiscriminatorMissing` — Union has object variants but no discriminator. Deserialization may be inefficient or ambiguous without a discriminator because each object variant must be tried in sequence.

Tracking it down found a single offender: `Card.stateReason`, which used `oneOf: [$ref CardStateReason, type: 'null']`. `oneOf` implies a tagged union — meaningful only with a discriminator — whereas this is really just a nullable enum. The idiomatic primitive for that is `anyOf`.

The existing spectral rule (`oneOf-must-have-discriminator`) didn't catch it for two reasons:
1. **Scope**: it only inspected `$.components.schemas[?(@.oneOf)]` — i.e. top-level schemas. Nested `oneOf` (inside `properties`, `allOf`, etc.) was invisible.
2. **Severity**: it was set to `warn`, so wouldn't have failed CI even if it had matched.

## Changes

### `openapi/components/schemas/cards/Card.yaml`
Change `stateReason` from `oneOf` → `anyOf`. No semantic change for consumers; just signals to codegen that this is a nullable value, not a tagged union.

```diff
 stateReason:
-  oneOf:
+  anyOf:
     - $ref: ./CardStateReason.yaml
     - type: 'null'
```

### `.spectral.yaml`
Broaden `oneOf-must-have-discriminator`:
- **Given path**: `$.components.schemas[?(@.oneOf)]` → `$..*[?(@ && @.oneOf)]`. Recursive descent with a null-safe filter so it catches `oneOf` at any depth (nested properties, allOf members, array items, etc.) without crashing on JSON null literals (`type: 'null'` etc.).
- **Severity**: `warn` → `error`. The only existing violation is fixed in this PR, so this won't regress CI.
- **Message**: updated to point devs at `anyOf` for nullable-value cases.

## Validation

- `make lint` exits 0 with the fix applied.
- Temporarily regressing `Card.yaml` back to `oneOf` makes spectral fail with:
  ```
  error  oneOf-must-have-discriminator
  components.schemas.Card.properties.stateReason
  ```

## Stack

Stacked on top of #520.
pengying added a commit that referenced this pull request May 29, 2026
…ation (#525)

## Summary

Bumps the Stainless edition and syncs several resource definitions to match the current API surface and codegen needs.

### Edition
- Bump root `edition: 2025-10-10` → `2026-05-06`.
- Drop the now-redundant pinned `kotlin.2025-10-08` edition; the new root edition covers it.

### Webhook discrimination
- `webhooks.unwrap`: add `discriminator: type` so the unwrap codegen dispatches on the payload's `type` field.
- New `openapi.transforms` entry: strip `type` from `BaseWebhook.properties` *and* `BaseWebhook.required`. Without this, every generated `*WebhookEvent` carries the full `WebhookType` enum on its `type` field via `BaseWebhook`, defeating the discriminator — variants that share the same `data` shape (e.g. multiple Card-related webhooks) become indistinguishable and the deserializer picks the first one declared. Same pattern already applied to customer / account / source / destination / auth base schemas in this file.

### Card refund (Kotlin keyword fix carry-over)
- Keep `refund: post /sandbox/cards/{id}/simulate/return` (the method key was renamed from `return` in #520 to avoid the Kotlin reserved keyword; preserved here through the edition bump).

### Resource cleanup — `customers`
- Drop the `customers.models` block. Customer / kyc / internal-account types are now exposed via `$shared.models` and resource subresources directly.
- Drop the standalone `create_kyc_link` method definition; the API surface is covered by `generate_kyc_link` (renamed earlier in #518).
- Simplify `update_internal_account` to the short form (the `body_param_name` was redundant).

### Resource cleanup — `auth`
- Move `auth_session` model alias from `sessions` → `credentials` (the canonical location for credential-related types).
- Drop the per-variant `*CredentialCreateRequest` / `*CredentialVerifyRequest` model aliases (`email_otp_*`, `oauth_*`, `passkey_*`) for the verify side. Stainless collapses these schemas to their `Fields` siblings after the existing `type`-strip transforms; exposing the wrapper aliases generated broken imports in the TS SDK (`TS2724` / `TS2552`). See #518 for the original diagnosis.
- Drop `auth_session_refresh_request` and the explicit `body_param_name` on `sessions.refresh`; covered by the new edition's defaults.

### New `$shared` models
Surface a few schemas that consumers need to reference directly:
- `individual_customer`, `business_customer`, `beneficial_owner`, `business_info_update`, `swift_beneficiary`

### `agents`
- Add `agent_account_rule` model alias.

## Stack

Stacked on top of #521.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant